package ntd.util.frame.task.handle.fm.util;

import cn.hutool.core.collection.CollStreamUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.date.LocalDateTimeUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import cn.hutool.log.StaticLog;
import com.c.opt.query.ComOptQueryWrapper;
import com.ToolOpt;
import com.modular.iot.bo.IotAttribute;
import com.modular.iot.bo.IotData;
import com.modular.iot.bo.IotDataItem;
import com.modular.iot.bo.IotModelBo;
import com.modular.iot.opt.OptDataFactorCom;
import ntd.util.fun.ComFun;
import ntd.util.modular.data.entity.DataAcquisitionRecords;
import ntd.util.modular.data.util.handle.constant.Constant212;
import com.c.Constant;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class ToolJsyData {

    private static final OptDataFactorCom DATA_FACTOR_OPT = ToolOpt.OPT_D_FACTOR;

    private static List<DataAcquisitionRecords> listDevice(String ruleId, Integer size) {
        ComOptQueryWrapper comOptQueryWrapper = ToolOpt.OPT_D_A_RECORDS.query()
                .ge("created_date", DateUtil.offsetHour(DateUtil.date(), -24).toStringDefaultTimeZone())
                .eq("data_acquisition_rule_id", ruleId);

        return ToolOpt.OPT_D_A_RECORDS.pageBean(comOptQueryWrapper, 1, ObjectUtil.defaultIfNull(size, 1));
    }

    private static Map<String, ComFun.FunInOut<DataAcquisitionRecords, List<IotModelBo>>> functionMap = new HashMap();

    static {
        // 金山云-海康-数据采集
        functionMap.put("402809817f97b548017f9c30855900d8", dataAcquisitionRecords -> {
            List<IotModelBo> iotModelBos = new ArrayList<>();

            String content = dataAcquisitionRecords.getContent();

            if (!JSONUtil.isTypeJSONObject(content)) {
                return iotModelBos;
            }

            JSONArray list = JSONUtil.parseObj(content).getJSONObject("data").getJSONArray("list");

            for (int i = 0; i < list.size(); i++) {
                JSONObject item = list.getJSONObject(i);
                LocalDateTime eventTime = LocalDateTimeUtil.parse(item.getStr("eventTime"), Constant.DATE_FORMAT_WLW_THREE);

                IotModelBo iotModelBo = new IotModelBo();
                iotModelBo.setStatus(item.getInt("status"));
                iotModelBo.setCode(item.getStr("deviceNo"));

                // 数据封装
                IotData iotData = new IotData();
                iotData.setMn(item.getStr("deviceNo"));
                iotData.setReportTime(eventTime);
                iotData.setOriginMsg(content);
                iotData.setCn(Constant212.CN_2011);
                iotData.setSt(Constant212.ST_61);

                // 角度校正
                iotData.addDataItem(new IotDataItem(DATA_FACTOR_OPT.getByCode("角度").getCode(), "角度", angleRevise(item.getInt("angle")).toString()));
                iotData.addDataItem(new IotDataItem(DATA_FACTOR_OPT.getByCode("气体浓度").getCode(), "气体浓度", "0"));
                iotData.addDataItem(new IotDataItem(DATA_FACTOR_OPT.getByCode("温度").getCode(), "温度", item.getStr("temp")));
                iotData.addDataItem(new IotDataItem(DATA_FACTOR_OPT.getByCode("震动次数").getCode(), "震动次数", item.getStr("shakeSize")));

                // 配置信息
                iotModelBo.addAttribute(IotAttribute.init(DATA_FACTOR_OPT.getByCode("电压").getCode(), "电压", item.getStr("voltage")));
                iotModelBo.setIotData(iotData);
                iotModelBos.add(iotModelBo);
            }

            return iotModelBos;
        });
        // 金山云-拓扑索尔-数据采集
        functionMap.put("402896817f969933017f96aa34c10007", dataAcquisitionRecords -> {
            String content = dataAcquisitionRecords.getContent();

            if (!JSONUtil.isTypeJSONObject(content)) {
                return new ArrayList<>();
            }

            final String[] typeNames = {"", "压力", "液位", "温度"};

            JSONObject item = JSONUtil.parseObj(content).getJSONObject("service").getJSONObject("data");

            LocalDateTime connTime = LocalDateTimeUtil.parse("20" + item.getStr("sendTime"), Constant.DATE_FORMAT_WLW_TWO);

            IotModelBo iotModelBo = new IotModelBo();
            iotModelBo.setLastConnTime(connTime);
            iotModelBo.setCode(item.getStr("Imei"));

            IotData iotData = new IotData();
            iotData.setOriginMsg(content);
            iotData.setCn(Constant212.CN_2011);
            iotData.setSt(Constant212.ST_61);

            iotData.setMn(item.getStr("Imei"));
            iotData.setReportTime(connTime);

            String typeName = typeNames[item.getInt("deviceType")];

            iotData.addDataItem(new IotDataItem(DATA_FACTOR_OPT.getByCode(typeName).getCode(), typeName,
                    UtilDataTpse.transform(item.getStr("sampleData"))).setFactoryUnit(item.getStr("unit")));

            // 配置信息
            iotModelBo.addAttribute(IotAttribute.init(DATA_FACTOR_OPT.getByCode("batteryLevel").getCode(), "电量",
                    item.getStr("batteryLevel"), item.getStr("%")));
            iotModelBo.addAttribute(IotAttribute.init(DATA_FACTOR_OPT.getByCode("signalStrength").getCode(), "信号强度",
                    item.getStr("signalStrength"), item.getStr("%")));

            iotModelBo.setIotData(iotData);
            return ListUtil.of(iotModelBo);
        });
        // 金山云-有毒有害气体-数据采集
        functionMap.put("402896817f8b509e017f8b59acc90008", dataAcquisitionRecords -> {
            String content = dataAcquisitionRecords.getContent();
            if (!JSONUtil.isTypeJSONObject(content)) {
                return new ArrayList<>();
            }
            JSONObject jsonObj = JSONUtil.parseObj(content).getJSONObject("data");
            if (ObjectUtil.isNull(jsonObj)) {
                return ListUtil.of();
            }
            LocalDateTime connDate = LocalDateTimeUtil.parse(jsonObj.getStr("connDate"), Constant.DATE_FORMAT_STAND);

            IotModelBo iotModelBo = new IotModelBo();
            iotModelBo.setName(jsonObj.getStr("deviceName"));
            iotModelBo.setCode(jsonObj.getStr("deviceNo"));
            iotModelBo.setLastConnIp(jsonObj.getStr("deviceIP"));
            iotModelBo.setLastConnTime(connDate);

            IotData iotData = new IotData();
            iotData.setMn(jsonObj.getStr("deviceNo"));
            iotData.setOriginIp(jsonObj.getStr("deviceIP"));
            iotData.setReportTime(connDate);
            iotData.setOriginMsg(content);
            iotData.setCn(Constant212.CN_2011);
            iotData.setSt(Constant212.ST_61);

            JSONArray sensors = jsonObj.getJSONArray("sensors");

            for (int i = 0; i < sensors.size(); i++) {
                JSONObject item = sensors.getJSONObject(i);
                IotDataItem iotDataItem = new IotDataItem();
                iotDataItem.setDataTime(item.getLocalDateTime("time", LocalDateTime.now()));
                iotDataItem.setFactorVal(item.getStr("value"));
                iotDataItem.setFactoryUnit(item.getStr("unit"));
                iotDataItem.setFactorCode(DATA_FACTOR_OPT.getByCode(item.getStr("name")).getCode());
                iotDataItem.setFactorName(item.getStr("name"));
                iotData.addDataItem(iotDataItem);
            }

            iotModelBo.setIotData(iotData);
            return ListUtil.of(iotModelBo);
        });
        // 金山云-液位-实时数据
        functionMap.put("40288a9e7f62e50c017f62e9f8130003", dataAcquisitionRecords -> {
            String content = dataAcquisitionRecords.getContent();
            JSONArray monitorings = JSONUtil.parseObj(content).getJSONArray("monitorings");
            if (CollectionUtil.isEmpty(monitorings)) {
                return ListUtil.of();
            }
            String mn = StrUtil.sub(dataAcquisitionRecords.getRequestUrl(), 42, 51);

            IotData iotData = new IotData();
            iotData.setMn(mn);
            iotData.setOriginMsg(content);
            iotData.setCn(Constant212.CN_2011);
            iotData.setSt(Constant212.ST_61);

            // 配置信息
            IotModelBo iotModelBo = new IotModelBo(iotData);

            for (int i = 0; i < monitorings.size(); i++) {
                JSONObject item = monitorings.getJSONObject(i);
                String factorCode = DATA_FACTOR_OPT.getByCode(item.getStr("monitoringName")).getCode();
                String factorName = item.getStr("monitoringName");
                String dataValue = item.getStr("dataValue");
                String unit = item.getStr("unit");
                LocalDateTime dataTime = item.getLocalDateTime("dataTime", LocalDateTime.now());
                if ("液位".equals(factorName)) {
                    iotData.setReportTime(dataTime);
                    IotDataItem iotDataItem = new IotDataItem();
                    iotDataItem.setDataTime(dataTime);
                    iotDataItem.setFactorCode(factorCode);
                    iotDataItem.setFactorName(factorName);
                    iotDataItem.setFactoryUnit(unit);
                    iotDataItem.setFactorVal(dataValue);
                    iotData.addDataItem(iotDataItem);
                } else {
                    iotModelBo.addAttribute(IotAttribute.init(factorCode, factorName, dataValue, unit, dataTime));
                }
            }
            iotModelBo.setCode(mn);
            return ListUtil.of(iotModelBo);
        });
    }

    private static Integer angleRevise(Integer angle) {
        if (angle > 150) {
            angle = 180 - angle;
        }
        return angle;
    }

    
    public static Map<String, List<IotModelBo>> getDeviceMap() {
        List<String> ruleIds = ListUtil.of("402809817f97b548017f9c30855900d8", "402896817f969933017f96aa34c10007",
                "402896817f8b509e017f8b59acc90008", "40288a9e7f62e50c017f62e9f8130003");

        List<IotModelBo> dataTempBOList = new ArrayList<>();
        for (String ruleId : ruleIds) {
            for (DataAcquisitionRecords dataAcquisitionRecord : listDevice(ruleId, 5)) {
                String content = dataAcquisitionRecord.getContent();
                if (StrUtil.isNotBlank(content)) {
                    try {
                        dataTempBOList.addAll(functionMap.get(ruleId).accept(dataAcquisitionRecord));
                    } catch (Exception e) {
                        throw new RuntimeException(e);
                    }
                }
            }
        }

        return CollStreamUtil.groupByKey(dataTempBOList, IotModelBo::getCode);
    }

    
    public static List<IotModelBo> getIotBo() {
        List<String> ruleIds = ListUtil.of("402809817f97b548017f9c30855900d8", "402896817f969933017f96aa34c10007",
                "402896817f8b509e017f8b59acc90008", "40288a9e7f62e50c017f62e9f8130003");

        List<IotModelBo> dataTempBOList = new ArrayList<>();
        for (String ruleId : ruleIds) {
            for (DataAcquisitionRecords dataAcquisitionRecord : listDevice(ruleId, 5)) {
                String tenantId = dataAcquisitionRecord.getTenantId();
                String content = dataAcquisitionRecord.getContent();
                if (StrUtil.isNotBlank(content)) {
                    List<IotModelBo> accept = null;
                    try {
                        accept = functionMap.get(ruleId).accept(dataAcquisitionRecord);
                        accept.forEach(iotModelBo -> iotModelBo.getIotData().setTenantId(tenantId));
                        dataTempBOList.addAll(accept);
                    } catch (Exception e) {
                        StaticLog.error(e);
                    }
                }
            }
        }

        return dataTempBOList;
    }

    public static void main(String[] args) {
        List<IotModelBo> iotModelBo = getIotBo();
        for (IotModelBo bo : iotModelBo) {
            ToolOpt.OPT_T_DATA.saveIot(bo);
        }
//        StaticLog.info(ToolOpt.OPT_D_FACTOR.getByCode("压力").getCode());
    }
}
